package com.example.spring.jdbc.service.impl;

import com.example.spring.jdbc.dao.RougeDao;
import com.example.spring.jdbc.service.RougeService;
import com.example.spring.jdbc.service.dto.BrandInfo;
import com.example.spring.jdbc.service.dto.RougeInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.List;

/**
 * @author : zhayh
 * @date : 2021-3-31 20:13
 * @description :
 */

@Slf4j
@Service("rougeService")
public class RougeServiceImpl implements RougeService {
    @Resource
    private RougeDao rougeDao;

    @Override
    public List<BrandInfo> getAllBrandInfo() {
        return rougeDao.getAllBrandInfo();
    }

    @Override
    public RougeInfo getRougeById(Long id) {
        return rougeDao.selectById(id);
    }

    @Override
    public RougeInfo addRouge(RougeInfo rougeInfo) {
        return rougeDao.insert(rougeInfo);
    }

    @Override
    public RougeInfo updateRougePrice(Long id, Float price) {
        return rougeDao.updatePrice(id, price);
    }

    @Override
    public Boolean deleteRouge(Long id) {
        return rougeDao.delete(id) > 0;
    }

    @Override
    public Page<RougeInfo> getRougesByPage(Integer pageIndex, Integer pageSize) {
        return rougeDao.selectByPage(pageIndex, pageSize);
    }

    @Override
    public Page<RougeInfo> getRougesByKeyword(String keyword, Integer pageIndex, Integer pageSize) {
        return rougeDao.selectByKeyword(keyword, pageIndex, pageSize);
    }

    // Spring的事务管理
    private boolean updateContents(Long id, String name, Float price) throws Exception {
        RougeInfo rougeInfo = rougeDao.updatePrice(id, price);
        if (rougeInfo != null) {
            log.info("更新后的价格：{}", rougeInfo.getRougePrice());
            if (rougeDao.updateName(id, name) != null) {
                log.info("更新后的信息：{} - {}", rougeInfo.getRougePrice(), rougeInfo.getRougeName());
                return true;
            }
        }
        throw new Exception("参数异常，更新失败");
    }

    // 使用模板事务管理器对象进行编程式事务
    @Resource
    private TransactionTemplate transactionTemplate;

    public void testTransaction(Long id, String name, Float price) {
        // 使用TransactionCallback或者TransactionCallbackWithoutResult执行事务
        transactionTemplate.execute(transactionStatus -> {
            try {
                return updateContents(id, name, price);
            } catch (Exception e) {
                // 发生异常，进行回滚
                log.info("发生异常： {}", e.getMessage());
                transactionStatus.setRollbackOnly();
                return false;
            }
        });
    }

    // 使用平台事务管理器对象进行编程式事务
    @Resource
    private PlatformTransactionManager ptm;

    public void testTransaction(Long id, String name) {
        // 获取默认事务定义
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        // 设置事务传播行为
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        // 根据事务定义对象设置的属性，获取事务状态
        TransactionStatus status = ptm.getTransaction(def);
        try {
            // 执行业务代码
            updateContents(id, name, 99f);
            // 事务提交
            ptm.commit(status);
        } catch (Exception e) {
            log.info("发生异常：{}", e.getMessage());
            // 事务回滚
            ptm.rollback(status);
        }
    }

    @Transactional
    @Override
    public boolean testRuntimeExceptionTransaction(Long id, String name, Float price) {
        RougeInfo rougeInfo = rougeDao.updatePrice(id, price);
        if (rougeInfo != null) {
            log.info("更新后的价格：{}", rougeInfo.getRougePrice());
            if (rougeDao.updateName(id, name) != null) {
                log.info("更新后的信息：{} - {}", rougeInfo.getRougePrice(),
                        rougeInfo.getRougeName());
                return true;
            }
        }
        throw new RuntimeException("参数异常，更新失败");
    }

    @Transactional
    @Override
    public boolean testCheckedExceptionTransaction(Long id, String name, Float price) throws SQLException {
        RougeInfo rougeInfo = rougeDao.updatePrice(id, price);
        if (rougeInfo != null) {
            log.info("更新后的价格：{}", rougeInfo.getRougePrice());
            if (rougeDao.updateName(id, name) != null) {
                log.info("更新后的信息：{} - {}", rougeInfo.getRougePrice(), rougeInfo.getRougeName());
                return true;
            }
        }
        throw new SQLException("SQL参数异常， 记录不回滚");
    }
}

// 圣罗兰 YSL 口红哑光细管纯口红小金条21号 2.2g【复古正红色 雾面哑光 生日礼物送女友】

